package mfuny.ggongal.admin.http;

import java.sql.Timestamp;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import mfuny.ggongal.admin.Server;
import mfuny.ggongal.admin.ad.AdDao;
import mfuny.ggongal.admin.ad.AdDetail;
import mfuny.ggongal.admin.ad.MissionDetail;
import mfuny.ggongal.admin.debug.Debug;
import mfuny.ggongal.admin.etc.Module;
import mfuny.ggongal.admin.games.GameDao;
import mfuny.ggongal.admin.json.JsonCreater;
import mfuny.ggongal.admin.mygift.MyGiftService;
import mfuny.ggongal.admin.play.PlayDao;
import mfuny.ggongal.admin.play.PlayService;

import org.json.simple.JSONObject;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import com.ibatis.sqlmap.client.SqlMapClient;

public class HttpGame {
	SqlMapClient sqlMapper;
	JsonCreater jc;
	MyGiftService mgs;
	
	public HttpGame() throws Exception {
		sqlMapper = Server.getSqlMapper();
		jc = new JsonCreater();
		mgs = new MyGiftService();
	}
	
	//게임시작시..
	@SuppressWarnings({ "deprecation", "unchecked" })
	public JSONObject game_start(HashMap<String, Object> params) throws Exception {
		JSONObject json = new JSONObject();
		int play_no = 0;
		//게임 플레이 번호 가져오기.
		play_no = sqlMapper.update("play_start", params);
		if (play_no > 0) {
			play_no = (Integer) sqlMapper.queryForObject("play_newNo", params);
		}
		
		//해당 게임 광고가져오기.
		AdDao ad = (AdDao)sqlMapper.queryForObject("ad_selectNo", Integer.parseInt((String)params.get("ad_no")));
		
		//경품게임일 경우..
		if ( ad.getService().equals("special") ) {
			//게임시작시간이 해당 경품게임 시간을 지났는지 확인 (vc-23).
			HashMap<String, Object> play = (HashMap<String, Object>)sqlMapper.queryForObject("play_selectByNoForHashMap", play_no);
			int hour = AdDetail.ad_getHourToday(ad);
			int playHour = new Date(((Timestamp)play.get("gamestarttime")).getTime()).getHours();
			if( playHour >= hour + AdDetail.vc27Hour ) {
				json.put("play_no", -1);
				return json;
			}
			
			//내 랭킹 구하기를 이용하여 미션을 성공한적이 있는지 여부 확인.
			//starttime 만들기.
			Date starttime = new Date();
			starttime.setHours(hour);
			starttime.setMinutes(0);
			starttime.setSeconds(0);
			//내 랭킹 구하기 해쉬맵 파라미터 완료.
			params.put("starttime", starttime);
			params.put("hour", AdDetail.vc27Hour);
			params.put("minute", AdDetail.vc27Minute);
			HashMap<String, Object> resultMap = (HashMap<String, Object>) sqlMapper.queryForObject("play_getRankByIdForSpecial27", params);
			int myRank = resultMap == null ? 0 : (int)(double)Double.parseDouble(resultMap.get("rank").toString());
			//해당게임 미션 성공이 있으면 1, 없으면 0.
			json.put("doGame", myRank > 0 ? 1 : 0);
		}
		json.put("play_no", play_no);
		return json;
	}
	
	//게임 종료시 랭킹만...
	public JSONObject game_getRank(HashMap<String, Object> params) throws Exception {
		
		JSONObject json = new HttpAd().ad_getRankForGameEnd(
				(String)params.get("id"),
				Integer.parseInt((String)params.get("ad_no")),
				0,
				null
			);
		
		return json;
	}
	
	//게임종료시..
	@SuppressWarnings({ "unchecked", "deprecation" })
	public JSONObject game_end(HashMap<String, Object> params) throws Exception {
		JSONObject json = new JSONObject();
		int result = sqlMapper.update("play_end", params);
		if(result > 0) {
			PlayDao myPlay = (PlayDao) sqlMapper.queryForObject("play_selectByNo", Integer.parseInt((String)params.get("no")));
			AdDao ad = (AdDao) sqlMapper.queryForObject("ad_selectNo", myPlay.getAd_no());
			
			//꽁게임 처리.
			if(whatService(myPlay).equals("ggong")) {
				json.put("service", ad.getService());
				//미션 성공시.
				if(isMissionClear(myPlay)) {
					HashMap<String, Object> paramMap = new HashMap<String, Object>();
					paramMap.put("id", myPlay.getId());
					paramMap.put("ggong", getOfferGgong(myPlay));
					paramMap.put("reason", "꽁게임 미션 달성");
					new HttpUser().user_addGgong(paramMap);
					
					json.put("addGgong", paramMap.get("ggong"));
					json.put("missionClear", 1);
				}
				//미션 실패시.
				else {
					json.put("missionClear", 0);
				}
			}
			//스페셜게임 처리.
			else if(whatService(myPlay).equals("special")) {
				json = new HttpAd().ad_getRankForGameEnd(myPlay.getId(), myPlay.getAd_no(), 0, null);
				
				//현재 시간이 경품게임 시간을 지났을 경우 responseCode = 2.
				//현재는 마감시간 0분(정시)까지..
				Date closeTime = Module.strToDate(ad.getDays());
				closeTime.setHours(closeTime.getHours() + 3);
				closeTime.setMinutes(0);
				closeTime.setSeconds(0);
				if( System.currentTimeMillis() >= closeTime.getTime()) {
					json.put("responseCode", 2);
				}
				
				if( isMissionClear(myPlay) ) {									//미션 성공시.
					setSpecialChecker1(myPlay);								//스페셜체커1 처리.
				}
			}
		}
		
		return json;
	}
	
	//상품 받을지 여부 처리.
	public int game_setReceive(int mygift_no, int receive) throws Exception {
		return mgs.setIsReceive(mygift_no, receive);
	}
	
	
	//당첨자 리스트 가져오기.
	public JSONObject getWinnerList(PlayDao myPlay) throws Exception {
		List<Object> winnerList = new PlayService().getWinnerForAd(myPlay.getAd_no(), myPlay.getGamestarttime());
		JSONObject json = jc.getJsonByMapList(winnerList, "rank");
		return json;
	}
	
	//특정 ID 당첨여부 확인(타임게임).
	public boolean isWin(PlayDao myPlay) throws Exception {
		boolean isWin = false;
		int myRank = getMyRank(myPlay);
		AdDao ad = (AdDao) sqlMapper.queryForObject("ad_selectNo", myPlay.getAd_no());
		List<Integer> winRankNumList = MissionDetail.getWinRankNum_mission(ad.getMission());
		
		for(int i = 0; i < winRankNumList.size(); i++) {
			if(winRankNumList.get(i) == myRank) {
				isWin = true;
			}
		}
		
		return isWin;
	}
	
	//특정 ID 등수 구하기.
	@SuppressWarnings({ "unchecked", "deprecation" })
	public int getMyRank(PlayDao myPlay) throws Exception {
		AdDao ad = (AdDao) sqlMapper.queryForObject("ad_selectNo", myPlay.getAd_no());
		HashMap<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("ad_no", myPlay.getAd_no());
		paramMap.put("score", MissionDetail.getScore_mission(ad.getMission()));
		Date starttime = (Date)myPlay.getGamestarttime();
		starttime.setMinutes(0);
		starttime.setSeconds(0);
		paramMap.put("starttime", starttime);
		
		Date endtime = (Date)starttime.clone();
		endtime.setHours(endtime.getHours() + 1);
		paramMap.put("endtime", endtime);
		paramMap.put("id", myPlay.getId());
		paramMap.put("hour", AdDetail.vc27Hour);
		paramMap.put("minute", AdDetail.vc27Minute);
		
		String sql = "";
		if(ad.getService().equals("special")) {
			sql = "play_getRankByIdForSpecial27";
		}
		
		HashMap<String, Object> resultMap = (HashMap<String, Object>) sqlMapper.queryForObject(sql, paramMap);
//		Object obj = resultMap.get("rank");
		int result = resultMap == null ? 0 : (int)(double)Double.parseDouble(resultMap.get("rank").toString());
		
		return result;
	}
	
	//특정 ID 미션 성패 여부.
	public boolean isMissionClear(PlayDao myPlay) throws Exception {
		AdDao ad = (AdDao) sqlMapper.queryForObject("ad_selectNo", myPlay.getAd_no());
		int m_score = MissionDetail.getScore_mission(ad.getMission());
		
		if(myPlay.getScore() >= m_score) {
			return true;
		} else {
			return false;
		}
	}
	
	//특정 게임 꽁 제공량 가져오기.
	public int getOfferGgong(PlayDao myPlay) throws Exception {
		AdDao ad = (AdDao) sqlMapper.queryForObject("ad_selectNo", myPlay.getAd_no());
		String m_offerggong = MissionDetail.getOfferGgong_mission(ad.getMission());
		int offerGgong = 0;
		if(m_offerggong.equals("default")) {
			GameDao game = (GameDao) sqlMapper.queryForObject("games_selectNo", ad.getGame_no());
			int offerGgongPer = Integer.parseInt(game.getOfferggong());
			offerGgong = Math.round(myPlay.getScore() / 100.0f * offerGgongPer);
		} else {
			offerGgong = Integer.parseInt(m_offerggong);
		}
		
		return offerGgong;
	}
	
	//특정 게임 서비스(카테고리) 가져오기.
	public String whatService(PlayDao myPlay) throws Exception {
		AdDao ad = (AdDao) sqlMapper.queryForObject("ad_selectNo", myPlay.getAd_no());
		return ad.getService();
	}
	
	//스페셜게임 당첨시 처리1.
	public void setSpecialChecker1(PlayDao myPlay) throws Exception {
		AdDao ad = (AdDao)sqlMapper.queryForObject("ad_selectNo", myPlay.getAd_no());
//		int startHour = -1;
//		try{
//			startHour = AdDetail.ad_getHourToday(ad);
//			if(startHour < 0 ) {
//				throw new Exception("ad_getHourToday error");
//			}
//		}catch(Exception e) {
//			startHour = 0;
//		}
		
		Date days = AdDetail.ad_getDateForSGame(ad);
		
		HashMap<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("user_id", myPlay.getId());
		paramMap.put("ad_no", myPlay.getAd_no());
		paramMap.put("days", days);
		
		//이미 성공하여 db에 있는지 확인.
		int result = (Integer)sqlMapper.queryForObject("spec_checkAlreadyReg", paramMap);
		if(result <= 0) {
			result = sqlMapper.update("spec_insert", paramMap);
			if(result <= 0) {
				throw new Exception("error sql-id : \"spec_insert\"");
			}
		}
	}
	
	
	//당첨자 가져오기 테스트용.
	@SuppressWarnings("deprecation")
	public JSONObject winner() throws Exception {
		Date time = new Date();
		time.setDate(10);
		time.setHours(18);
		time.setMinutes(0);
		JSONObject json = jc.getJsonByMapList( new PlayService().getWinnerForAd(4, time), "winner");
		return json;
	}
	
	
	
	//base64 테스트.
	public String base64test() throws Exception {
		BASE64Encoder en = new BASE64Encoder();
		BASE64Decoder de = new BASE64Decoder();
		String result = "";
		String a = "{\"abc\":\"안녕하세요\"}";
		result = "인코딩전 기본 문자열 : <br/>";
		result += a + "<br/>";
		result += "인코딩 후 <br/>";
		result += en.encode(a.getBytes()) + "<br/>";
		result += "바로 디코딩 : <br/>";
		result += new String(de.decodeBuffer(en.encode(a.getBytes())));
		
		return result;
	}
	public String base64test2(String text) throws Exception {
		BASE64Decoder de = new BASE64Decoder();
		String result = "인코딩되어 온 문자열 : <br/>";
		result += text + "<br/>";
		result += "디코딩 후 문자열 : <br/>";
		result += new String(de.decodeBuffer(text));
		
		return result;
	}
	public String base64test3() throws Exception {
		String a ="{\"id\":\"hkpark\",\"reason\":\"한글 테스트 1234 abcd\",\"tag\":\"user_addGgong\",\"ggong\":-500}";
		
		BASE64Encoder en = new BASE64Encoder();
		BASE64Decoder de = new BASE64Decoder();
//		String jsonStr = new JsonCreater().getJsonByMap(h).toJSONString();
		String result = "jsonStr : " + a;
		String enStr = en.encode(a.getBytes());
		byte[] by = de.decodeBuffer(enStr);
		
		result += "인코딩 : " + enStr + "<br/>";
		result += "디코딩 : " + new String(by);
		
		return result;
	}
}
